Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 141949) +++ channels/chan_sip.c (working copy) @@ -2083,6 +2083,7 @@ /*--- Internal UA client handling (outbound registrations) */ static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us); static void sip_registry_destroy(struct sip_registry *reg); +static int remote_sip_register(const char *uname, const char *host, const char *sec, const char *auth, const char *port, const char *exten, const char *cmd); static int sip_register(const char *value, int lineno); static const char *regstate2str(enum sipregistrystate regstate) attribute_const; static int sip_reregister(const void *data); @@ -6306,6 +6307,115 @@ return NULL; } + +/*! \brief Manager API Action: Register uses this function to ADD or DEL remote user registration + * Contributed by Roger Leszczynski rogerles@gmail.com + */ +static int remote_sip_register(const char *uname, const char *host, const char *sec, const char *auth, const char *port, const char *exten, const char *cmd) +{ + struct sip_registry *reg = NULL; + + if (ast_strlen_zero(uname) || ast_strlen_zero(host)) { + ast_log(LOG_WARNING, "Improper Reg From Manager"); + return -1; + } + + if (port && !atoi(port)) { + ast_log(LOG_WARNING, "%s is not a valid port number", port); + return -1; + } + + + if (strcmp(cmd, "ADD") == 0) { + + ast_log(LOG_WARNING, "Sending Register out: %s@%s\n", uname, host); + + /* Similar to int sip_register */ + if (!(reg = ast_calloc(1, sizeof(*reg)))) { + ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); + return -1; + } + + if (ast_string_field_init(reg, 256)) { + ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); + free(reg); + return -1; + } + + regobjs++; + ASTOBJ_INIT(reg); + ast_string_field_set(reg, callback, exten); + ast_string_field_set(reg, username, uname); + ast_string_field_set(reg, hostname, host); + ast_string_field_set(reg, authuser, auth); + ast_string_field_set(reg, secret, sec); + reg->expire = -1; + reg->timeout = -1; + reg->refresh = default_expiry; + reg->portno = atoi(port); + reg->callid_valid = FALSE; + reg->ocseq = INITIAL_CSEQ; + ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ + __sip_do_register(reg); + } + if (strcmp(cmd, "DEL") == 0) { + + ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { + ASTOBJ_RDLOCK(iterator); + + if (strcmp(iterator->username, uname) == 0 && strcmp(iterator->hostname, host) == 0) + { + ast_log(LOG_WARNING, "Deleting Registration for: %s@%s\n", uname, host); + ASTOBJ_CONTAINER_UNLINK(®l, iterator); + sip_registry_destroy(iterator); + } + ASTOBJ_UNLOCK(iterator); + + } while(0)); + + } + return 0; +} + +/*! \brief Description for Manager API remote registration */ +static char mandescr_register[] = +"Description: Register a user to another server\n" +"Variables: \n" +" Username: username of sip uri\n" +" Secret: password\n" +" Authuser: Authorization username\n" +" Hostname: host to register to\n" +" Port: port\n" +" Exten: internal extension mapping for this user\n" +" Cmd: DEL or ADD\n"; + + +/*! \brief Manger API Action to register a client remotely */ +static int manager_act_register(struct mansession *s, struct message *m) +{ + int r; + const char *muname = astman_get_header(m, "Username"); + const char *msec = astman_get_header(m, "Secret"); + const char *mauth = astman_get_header(m, "AuthUser"); + const char *mhost = astman_get_header(m, "Hostname"); + const char *mport = astman_get_header(m, "Port"); + const char *mexten = astman_get_header(m, "Exten"); + const char *mcmd = astman_get_header(m, "Cmd"); + + if (ast_strlen_zero(muname) || ast_strlen_zero(msec) || ast_strlen_zero(mauth) || ast_strlen_zero(mhost) + ||ast_strlen_zero(mexten)|| ast_strlen_zero(mport) || ast_strlen_zero(mcmd)) { + astman_send_error(s, m, "Invalid Format"); + return 0; + } + r = remote_sip_register(muname, mhost, msec, mauth, mport, mexten, mcmd); + + return 0; +} + + + + + /*! \brief Parse register=> line in sip.conf and add to registry */ static int sip_register(const char *value, int lineno) { @@ -22614,6 +22724,8 @@ "Show SIP registrations (text format)", mandescr_show_registry); ast_manager_register2("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify, "Send a SIP notify", mandescr_sipnotify); + ast_manager_register2("Register", EVENT_FLAG_SYSTEM, manager_act_register, + "Register User", mandescr_register); sip_poke_all_peers(); sip_send_all_registers(); @@ -22672,6 +22784,7 @@ ast_manager_unregister("SIPqualifypeer"); ast_manager_unregister("SIPshowregistry"); ast_manager_unregister("SIPnotify"); + ast_manager_unregister("Register"); /* Kill TCP/TLS server threads */ if (sip_tcp_desc.master) @@ -22755,3 +22868,4 @@ .unload = unload_module, .reload = reload, ); +